package com.jule.teenpatti.game.network.protocol.reqs;

import JoloProtobuf.GameSvr.JoloGame;
import com.jule.core.common.log.LoggerUtils;
import com.jule.teenpatti.base.enums.ErrorCodeEnum;
import com.jule.teenpatti.base.enums.GameConst;
import com.jule.teenpatti.game.play.TableUtil;
import com.jule.teenpatti.log.service.LogReasons;
import com.jule.teenpatti.game.dao.bean.CommonConfigModel;
import com.jule.teenpatti.game.gameUtil.GameLogic;
import com.jule.teenpatti.game.model.PlayerInfo;
import com.jule.teenpatti.game.model.eenum.PlayerStateEnum;
import com.jule.teenpatti.game.network.protocol.ClientReq;
import com.jule.teenpatti.game.network.protocol.acks.JoloGame_GetSideShowStateAck_50009;
import com.jule.teenpatti.game.play.AbstractTable;
import com.jule.teenpatti.game.service.TableService;
import com.jule.teenpatti.game.service.TimerService;
import com.jule.teenpatti.game.utils.log.TableLogUtil;
import com.jule.teenpatti.game.vavle.notice.NoticeBroadcastMessages;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;

@Slf4j
public class JoloGame_GetSideShowStateReq_50009 extends ClientReq {
    private long time;
    public JoloGame_GetSideShowStateReq_50009(int functionId) {
        super(functionId);
    }

    private JoloGame.JoloGame_GetSideShowStateReq req;

    @Override
    public void readPayLoadImpl(ByteBuf buf) throws Exception {
        time = System.currentTimeMillis();
        byte[] blob = new byte[buf.readableBytes()];
        buf.readBytes(blob);
        req = JoloGame.JoloGame_GetSideShowStateReq.parseFrom(blob);
        AbstractTable table = TableService.getInstance().getTable(header.gameId+"",req.getRoomId(), req.getTableId());
        if(null != table){
            this.setTable(table);
        }else{
            log.error("桌子不存在,roomId->"+req.getRoomId()+", tableId->"+req.getTableId());
        }
    }

    @Override
    public void processImpl() throws Exception {
        log.debug("收到消息-> " + functionId + " reqNum-> " + header.reqNum + "msg ->" + req.toString());
        String userId = req.getUserId();
        String roomId = req.getRoomId();
        String tableId = req.getTableId();
        String gameOrderId = req.getGameOrderId();
        double betScore = 0;

        JoloGame.JoloGame_GetSideShowStateAck.Builder ack = JoloGame.JoloGame_GetSideShowStateAck.newBuilder();
        ack.setUserId(userId);
        ack.setRoomId(roomId);
        ack.setTableId(tableId);
        ack.setIsCanChooseTargetUser(0);
        ack.setGameOrderId(gameOrderId);
        ack.setBetScore(betScore);

        //获得桌子信息和玩家信息
        AbstractTable table = getTable();
        try{
            CommonConfigModel commonConfig = table.getCommonConfig();
            if(null == commonConfig){
                ack.setResult(-2);
                log.error("can't found CommonConfig, roomId->"+roomId+", tableId->"+tableId);
                ack.setResultMsg(ErrorCodeEnum.GAME_50009_1.getCode());
                ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack.build(), header));
                return;
            }

            PlayerInfo player = table.getPlayer(userId);

            if(player.getState() != PlayerStateEnum.beting){
                ack.setResult(-3);
                log.warn("玩家状态值不对， userId->{}, state->{}", player.getPlayerId(), player.getState());
                ack.setResultMsg(ErrorCodeEnum.GAME_50013_1.getCode());
                ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack.build(), header));
                return;
            }

            betScore = req.getBetScore();
//
//            if (betScore > table.getMaxBetScore()) {
//                ack.setResult(-4);
//                ack.setResultMsg("betScore greater than maximum -> " +
//                        "maxBetScore:"+table.getMaxBetScore()+" -> betScore:"+betScore);
//                ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack.build(), header));
//                return;
//            }

            //检查桌面积分是否足够
            if (player.getPlayScoreStore() < betScore) {
                ack.setResult(-5);
                log.error("score amount insufficient 。betScore->" + betScore + "：playScoreStore:"+player.getPlayScoreStore());
                ack.setResultMsg(ErrorCodeEnum.GAME_50001_4.getCode());
                ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack.build(), header));
                return;
            }

            //player.setPlayScoreStore(player.getPlayScoreStore() - betScore);//减去玩家桌面积分
            player.minusPlayScoreStore(betScore, LogReasons.CommonLogReason.GAME_SIDE_SHOW);
            TableLogUtil.sideShow(functionId,"sideShowState",userId,player.getNickName(),table.getPlayType()+"",
                    table.getRoomId(),table.getTableId(),table.getCurrGameOrderId(),betScore);
            table.setTotalAlreadyBet(table.getTotalAlreadyBet() + betScore); //桌内累计下注金额
            table.accumulativeBet(player.getPlayerId(),betScore);
            player.setState(PlayerStateEnum.already_bet);//修改玩家状态值为已下注
            player.setAlreadyBetScore4Round(betScore);
            player.setTotalAlreadyBetScore4Hand(player.getTotalAlreadyBetScore4Hand() + betScore);//累计玩家总得下注值

            //发送通知
            NoticeBroadcastMessages.moneyChangeNotice(table,userId,player.getPlayScoreStore());

            //广播玩家下注
            NoticeBroadcastMessages.betRoundDoBet(table,table.getCurrRoundId(),player, null,false);

            //找到可以进行比牌的用户列表
            if(commonConfig.isChooseSideShowUser()){
                for(PlayerInfo playerInfo : table.getInGamePlayers().values()){
                    if(playerInfo.getState() != PlayerStateEnum.fold && playerInfo.getState() != PlayerStateEnum.showfail
                            && !playerInfo.getPlayerId().equals(player.getPlayerId())){
//                            && playerInfo.getIsBlind() != 1){ //去掉自己并且对方已经开牌
                        ack.addCanChooseTargetUserList(JoloGame.JoloGame_TablePlay_PlayerSeatInfo.newBuilder()
                                .setUserId(playerInfo.getPlayerId())
                                .setSeatNum(playerInfo.getSeatNum())
                                .build()
                        );
                    }
                }
            }

            ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack
                    .setBetScore(betScore)
                    .setResult(1)
                    .setCurrPlayScore(player.getPlayScoreStore())
                    .setIsCanChooseTargetUser(commonConfig.isChooseSideShowUser()? 1 : 0)
                    .build(), header));

            table.setLastActionTime(System.currentTimeMillis());

            //如果允许选择被比牌用户，那么发送notice，通知客户端显示等待选择用户倒计时
            if(commonConfig.isChooseSideShowUser()){
                //停止本牌桌现在进行中的倒计时
                TimerService.getInstance().delTimerTask(table.getRoomTableRelation());
                //开启等待选择用户倒计时
                GameLogic.waitChooseUserCD(table, player);

                //发送通知给全部客户端，进入倒计时显示
                try{
                    NoticeBroadcastMessages.sideShowWaitChooseUser(table, player);
                }catch (Exception ex){
                    log.error("SendNotice ERROR：", ex);
                }
            } else{
                //如果用户在倒计时内没有选择用户，那么默认与上家比牌
                PlayerInfo targetPlayer = TableUtil.getPreBetPlayer(table,player.getSeatNum());
                log.debug("当前的玩家："+player.playerToString());
                log.debug("上一个玩家："+targetPlayer.playerToString());
                //记录当前发起比牌者的id
                table.setCurrDoSideShowPlayerId(player.getPlayerId());

                if(commonConfig.isChooseSideShowUser()) {
                    //广播事件：通知所有牌桌内玩家，需要等待指定玩家是否同意比牌的倒计时
                    NoticeBroadcastMessages.sideShowWaitTargetUserAllow(table, targetPlayer.getPlayerId());
                    GameLogic.waitUserAllowSideShowCD(table, player, targetPlayer);
                }else{
                    List<String> list = new ArrayList<>();
                    list.add(player.getPlayerId());
                    list.add(targetPlayer.getPlayerId());
                    //通知所有人有人sideshow
                    NoticeBroadcastMessages.bothSideshows(table,list);
                    //启动比牌倒计时
                }
            }
            long timeMillis = System.currentTimeMillis() - time;
            if(timeMillis> GameConst.COST_TIME) {
                LoggerUtils.performance.info("GetSideShowStateReq_50009,cost time:{},req:{}", timeMillis, req.toString());
            }
        }catch (Exception ex){
            log.error("系统异常：userId->"+userId+", roomI->"+roomId+", tableId->"+tableId+", message->"+ex.getMessage());
            ack.setResult(-1);
            ack.setResultMsg(ErrorCodeEnum.GAME_50002_2.getCode());
            ctx.writeAndFlush(new JoloGame_GetSideShowStateAck_50009(ack.build(), header));
        }finally {
            log.debug("GetSideShowState ACK info: "+ack.toString());
            log.debug("GetSideShowState ACK bytes length: "+ack.build().toByteArray().length);
            if(null != table){
                log.debug("All Player info: "+System.getProperty("line.separator") + TableUtil.toStringAllPlayers(table));

                log.debug("InGame Player info: "+System.getProperty("line.separator") + TableUtil.toStringInGamePlayers(table));
            }
            log.debug("GetSideShowState over. Table state: "+table.getTableStateEnum());

            long useTimes = System.currentTimeMillis() - time;
            if(useTimes > 500) {
                log.error("GetSideShowState。 耗时->{} 毫秒, reqNum->{}", useTimes, header.reqNum); //TODO:临时增加
            }
        }
    }
}
